using System;
using System.Collections;
using System.Text;
using AllegNet;

namespace DemonHunter
{
    class Game : Api
    {
        private static Game game;

        private Bmp gameBitmap;

        private Logic logic;
        private Level level;
        private Sound music;
        private UI userInterface;

        private int frameCount;
        private int fps;

        public Game()
        {
            game = this;
            
            // Initialize AllegNet
            AllegNetInit();

            // Install keyboard (for use with AllegNet)
            InstallKeyboard();
            
            // Install timer (for use with AllegNet, specifically mouse)
            InstallTimer();

            //Install sound
            InstallSound(DigiWindows.DigiAutoDetect, MidiWindows.MidiNone, "");
            
            // Set color depth to 32 bit
            SetColorDepth(CDepth.Depth_16_Bits);

            // Set render mode to page flipping using video RAM (this gives best performance)
            SetRenderMode(RenderingModes.PageFlipping, BmpType.Video);

            // Initialize video card to 1024x768, full screen
            SetGfxMode(GfxModes.GfxAutoDetectFullScreen, ScreenResolution.Size_1024_768);

            // Create a bitmap in video memory for the game screen (video memory is preffered over system RAM)
            gameBitmap = CreateVideoBitmap(ScreenWidth, ScreenHeight);// - 128);
            ClearBitmap(gameBitmap);

            // Create instances of Level, Logic, and Music classes
            level = new Level();
            logic = new Logic();
            music = new Sound();
            userInterface = new UI();

            Sound.playSound(Sound.SOUND_MUSIC);


            // Refresh screen until game is over
            DateTime start = DateTime.Now;
            
            while (!KbKey[AllKeys.Esc])
            {
                    frameCount++;
                    DateTime stop = DateTime.Now;
                    TimeSpan delay = stop - start;
                    if (delay.Seconds == 1)
                    {
                        start = DateTime.Now;
                        fps = frameCount;
                        frameCount = 0;
                        userInterface.Refresh();
                    }
                    logic.DoLogic();

                    // Draw UI window to bottom portion of screen
                    Blit(userInterface.GetBitmap(), gameBitmap, 0, 0, 0, ScreenHeight - 129, ScreenWidth, 128);

                    // Draw main game window to upper portion of screen
                    Blit(gameBitmap, BufferedScreen, 0, 0, 0, 0, gameBitmap.Width, gameBitmap.Height);
            }

            DestroyBitmap(gameBitmap);

            //Exit AllegNet
            UninstallAllegNet();
        }


       // private void RefreshScreen()
      //  {
            // Show FPS
            //if (showFPS)
                //TextOutEx(gameBitmap, DefaultFont, "FPS: " + fps.ToString(), 10, 10, System.Drawing.Color.Red, System.Drawing.Color.Transparent);

            // Show X-Location
              //  TextOutEx(gameBitmap, DefaultFont, "X: " + logic.GetXLoc(), 10, 20, System.Drawing.Color.Red, System.Drawing.Color.Transparent);

               // TextOutEx(gameBitmap, DefaultFont, "Player Y: " + PlayerCharacter.GetInstance().getEntityYLoc(), 10, 30, System.Drawing.Color.Red, System.Drawing.Color.Transparent);

            // Show speedModifer ********** REMOVE THIS LATER
               // TextOutEx(gameBitmap, DefaultFont, "speedModifier: " + logic.GetSpeedModifier(), 10, 40, System.Drawing.Color.Red, System.Drawing.Color.Transparent);
            

     //   }
        public void DrawScenery(double xLoc)
        {
            //initialize Bitmaps
            Bmp roadBitmap = level.GetRoadBitmap();
            Bmp backgroundBitmap = level.GetBackgroundBitmap();
            
            //draw road bitmap
            int roadOffset = (int)xLoc % roadBitmap.Width;
            Blit(roadBitmap, gameBitmap, roadOffset, 0, 0,
                backgroundBitmap.Height, roadBitmap.Width, roadBitmap.Height);

            for (int roadX = level.GetRoadBitmap().Width - roadOffset; roadX < ScreenWidth; roadX += level.GetRoadBitmap().Width)
                Blit(roadBitmap, gameBitmap, 0, 0, roadX,
                    backgroundBitmap.Height, roadBitmap.Width, roadBitmap.Height);

            //draw background
            int groundOffset = (int)(xLoc / 3) % backgroundBitmap.Width;
            
            //game backgrounds are 512x552 bitmaps 
            Blit(backgroundBitmap, gameBitmap, groundOffset, 0, 0, 0,
                backgroundBitmap.Width - groundOffset, backgroundBitmap.Height);

            for (int groundX = backgroundBitmap.Width - groundOffset; groundX < ScreenWidth; groundX += backgroundBitmap.Width)
                Blit(backgroundBitmap, gameBitmap, 0, 0, groundX, 0,
                    backgroundBitmap.Width, backgroundBitmap.Height);
           
        }
        public void DrawHero(PlayerCharacter player)
        {
            //PlayerCharacter player = level.getPlayerChar();
            Bmp playerBitmap = player.GetCurrentBitmap();
            //draw player bitmap
            MaskedBlit(playerBitmap, gameBitmap, 0, 0, (int)(player.getEntityXLoc() - logic.GetXLoc()),
                (int)player.getEntityYLoc(), playerBitmap.Width, playerBitmap.Height);
        }

        public void DrawEntities(double xLoc)
        {
            //draw enemies
            for (int i = 0; i < level.GetNumEntities(); i++)
            {
                Entity entity = level.GetEntity(i);
                Bmp entityBitmap = entity.GetCurrentBitmap();
                MaskedBlit(entityBitmap, gameBitmap, 0, 0, (int)(entity.getEntityXLoc() - logic.GetXLoc()),
                    (int)entity.getEntityYLoc(), entityBitmap.Width, entityBitmap.Height);
            }
        }

        public static Game GetInstance() { return game; }

        public int GetFPS() { return fps; }
    }
}
